#ifndef NIVEL_H_
#define NIVEL_H_
#include <map>
#include <jsoncpp/json/reader.h>
#include <jsoncpp/json/value.h>
#include <utility>
#include <list>
#include <string>
#include "Constantes.h"

#include "Candy.h"
#include "Regla.h"

#define NIVEL_MAXIMO 100
#define NIVEL_INICIAL 1

class Nivel {
  public:
    Nivel();
    ~Nivel();

    void cargarTablero(int nivel);

    static bool getJsonNivel(int nivel, Json::Value &jsonNivel);
    static bool nivelExiste(int nivel);

    void moverFicha(std::pair<int, int> origen,
        std::pair<int, int> destino, int &puntos, Json::Value& listaTableros);

    void obtenerJSonTablero(Json::Value& json_tablero);

    bool quedanMovimientos(int &fila, int &columna);

    int getPuntajeRequerido();
    int getCantColumnas();
    int getCantFilas();
    std::string getNombreNivel();
    std::string getSonidoMovimiento();
    std::string getSonidoCombinacion();

    /*  Para usar como seed de rand_r */
    void setSeed(unsigned int seed);

    int getMaxJugadores();
    std::string getImagenFondo();

    void imprimirTablero(bool sin_detalles = true);

    int estabilizarTablero(Json::Value* listaTableros,
                                  std::pair<int,int> destino);

    bool esOrientable(std::string candy, t_orientacion& orientacion,
                                    std::string& jsonName);

    bool movimientoValido(std::pair<int,int> origen,
                                  std::pair<int,int> destino);
  private:
    Candy ***board;

    Regla reglas;

    int cantColumnas;
    int cantFilas;

    std::string imagenFondo;
    int maxJugadores;
    std::string nombreNivel;
    int puntajeRequerido;
    std::string sonidoCombinacion;
    std::string sonidoMovimiento;

    std::map<std::string, double> probabilidadesCelda;
    std::map<std::string, double> probabilidadesColumna;

    Candy *candyFromString(std::string candy);
    Candy *randomCandy(bool celda);

    /* Metodos para calcular los tableros */
    bool tableroEstable();
    bool aplicarGravedad();
    bool completarTablero();
    void intercambiar(std::pair<int,int> origen,
                                  std::pair<int,int> destino);
    void setEstadoEstable();


    int aplicarReglas(std::pair<int, int> origen);
    unsigned int r_seed;
};

#endif
